package com.myway.service.payment.TBCPay.impl;

import com.myway.dao.FlyOrderMapper;
import com.myway.dao.FlyOrderPaymentMapper;
import com.myway.dao.PaymentMapper;
import com.myway.dao.TbcResultCodeMapper;
import com.myway.dto.common.JsonData;
import com.myway.dto.common.ResultEntity;
import com.myway.dto.order.domain.OrderStatus;
import com.myway.pojo.*;
import com.myway.service.OrderService;
import com.myway.service.TicketService;
import com.myway.service.payment.Oceanpayment.TBCPayService;
import com.myway.utils.http.HttpsUtils_p12;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.impl.client.DefaultHttpClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by qianmi-05 on 2018/9/19.
 */
@Service
@Slf4j
public class TBCPayServiceImpl extends DefaultHttpClient implements TBCPayService {

    @Autowired
    private FlyOrderMapper flyOrderMapper;

    @Autowired
    private PaymentMapper paymentMapper;

    @Autowired
    private FlyOrderPaymentMapper flyOrderPaymentMapper;

    @Autowired
    private TbcResultCodeMapper tbcResultCodeMapper;

    @Autowired
    private TicketService ticketService;

    @Autowired
    private OrderService orderService;


    @Override
    public String TBCToPay(String orderid) {
        if(StringUtils.isEmpty(orderid)){
            return  null;
        }
        FlyOrder flyOrder = flyOrderMapper.selectByPrimaryKey(Long.parseLong(orderid));
        if(flyOrder==null){
            return null;
        }
        String orderCurrenry = flyOrder.getOrderCurrenry();
        String currency="";
        if(orderCurrenry.equals("EUR")){
            currency="978";
        }else if(orderCurrenry.equals("USD")){
            currency="840";
        }else if(orderCurrenry.equals("CNY")){
            currency="156";
        }else if(orderCurrenry.equals("GEL")){
            currency="981";
        }
        double totalPriceDou = flyOrder.getTotalPrice() * 100;
        int totalPriceInt = (new Double(totalPriceDou)).intValue();
        String totalPrice = String.valueOf(totalPriceInt);
        //测试数据
        String contactName = flyOrder.getContactName();
        if(!StringUtils.isEmpty(contactName)&&contactName.equals("Yang Yuezhang")){
            totalPrice="1";
        }
//        currency="981";
//        String params = "command=v&amount="+totalPrice+"&currency="+currency+"&client_ip_addr=47.75.92.162&language=EN&description=UFCTEST&msg_type=SMS";
//
//        Map<String,String> map=new HashMap<String,String>();
//        map.put("params",params);
//
//        String httpsUrl = "https://ecommerce.ufc.ge:18443/ecomm2/MerchantHandler";
//        String transactionId = HttpClientUtil.doPost("http://47.75.92.162:48082/tbcPay.php?params="+params, map);
//        String transactionIdReplace = transactionId.replaceAll("TRANSACTION_ID:", "");
//        String transId = transactionIdReplace.trim();
        try {
            String transactionId = HttpsUtils_p12.getTransId(totalPrice,currency);
            if(StringUtils.isEmpty(transactionId)){
                return null;
            }
            String transactionIdReplace = transactionId.replaceAll("TRANSACTION_ID:", "");
            String transId = transactionIdReplace.trim();
            return transId;
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 根据TransId 获取返回结果
     * @param transId
     * @return
     */
    @Override
    public String callBackByTransId(String transId) {
        if(StringUtils.isEmpty(transId)){
            return  null;
        }
        try {
//            transId=URLEncoder.encode(transId,"UTF-8");
//            String params ="command=c&trans_id="+transId+"&client_ip_addr=47.75.92.162";
//            Map<String,String> map=new HashMap<String,String>();
//            map.put("params",params);
//            String httpsUrl = "https://ecommerce.ufc.ge:18443/ecomm2/MerchantHandler";
//            String result= HttpClientUtil.doPost("http://47.75.92.162:48082/tbcPay.php?params="+params, map);
            String result = HttpsUtils_p12.getTransStatus(transId);
            return result;
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public String addTbcPaymentInfo(String orderId,String transId,String  result,String result_code,String DSECURE,String RRN,String APPROVAL_CODE,String BANK_ID,String callBackResultStr,String firstTransId,String type) {
        FlyOrder flyOrder = flyOrderMapper.selectByPrimaryKey(Long.parseLong(orderId));
        if(flyOrder==null){
            return  "error";
        }
        Payment payment=new Payment();
        if("task".equals(type)){
            payment.setPayType("task*tbc");
        }else{
            payment.setPayType("tbc");
        }
        payment.setAction("pay");//机票支付
        payment.setAmount(new BigDecimal(flyOrder.getTotalPrice()));
        payment.setPayTime(new Date());
        payment.setCurrency(flyOrder.getCurrency());
        payment.setPayer(flyOrder.getContactName());
        payment.setBankId(BANK_ID);
        payment.setTbc3dsecure(DSECURE);
        payment.setTbcApprovalCode(APPROVAL_CODE);
        payment.setTbcResultCode(result_code);
        payment.setTbcRrn(RRN);
        payment.setRemarks(callBackResultStr);
        payment.setLastTransactionId(transId);
        payment.setTransactionId(firstTransId);
        if(result!=null&&result.equals("OK")){
            payment.setPayStatus("PAID");
        }else{
            payment.setPayStatus("FAIL");
        }
       /* List<Integer> payRecordsList = flyOrderPaymentMapper.isPayRecords(String.valueOf(orderId));
        if (payRecordsList.size()>0) {
            payment.setId(payRecordsList.get(0).longValue());
            paymentMapper.updateByPrimaryKeySelective(payment);
            return "success";
        }*/
        int paymentNum = paymentMapper.insertSelective(payment);
        if(paymentNum>0){
            FlyOrderPayment flyOrderPayment=new FlyOrderPayment();
            flyOrderPayment.setPaymentId(payment.getId());
            flyOrderPayment.setAmount(new BigDecimal(flyOrder.getTotalPrice()));
            flyOrderPayment.setOrderNo(flyOrder.getId());
            int insertSelective = flyOrderPaymentMapper.insertSelective(flyOrderPayment);
            if(insertSelective<0){
                return  "error";
            }
        }else{
            return "error";
        }

        return "success";
    }

    @Override
    public FlyOrder selectByOrderId(String id) {
        if(id != null && id != ""  && id!= "null"){
            FlyOrder flyOrder =  flyOrderMapper.selectByPrimaryKey(Long.valueOf(id));
            return flyOrder;
        } else {
            return null;
        }

    }

    @Override
    public TbcResultCode getTbcResultCode(String resultCode) {
        if(StringUtils.isEmpty(resultCode)){
            return null;
        }
        TbcResultCode tbcResultCode = tbcResultCodeMapper.selectByPrimaryKey(resultCode);
        return tbcResultCode;
    }

    @Override
    public FlyOrder getOrderByFirstTransId(String transId) {
        if(StringUtils.isEmpty(transId)){
            return null;
        }
        List<FlyOrder> FlyOrderList = flyOrderMapper.getOrderByFirstTransId(transId);
        if(FlyOrderList.size()>0){
            return FlyOrderList.get(0);
        }
        return null;
    }

    @Override
    public ResultEntity TbcOKCallBackOutTicket(String orderId,String  lastTransId) {
        Map<String, Object> resultMap = new HashMap<String, Object>();
        FlyOrder flyOrder = null;
        if (orderId == "" || orderId == null || orderId == "null") {
            flyOrder = getOrderByFirstTransId(lastTransId);
            if (flyOrder == null) {
                log.info("====@@@@======FlyaymentController TBCOKCallBack=======>>>lastTrans_id There is no query order");
                resultMap.put("result", "FAILED!");
                resultMap.put("message","orderId is null || getOrderByFirstTransId(lastTrans_id) get data is null");
                return ResultEntity.fail("orderId is null || getOrderByFirstTransId(lastTrans_id) get data is null",500,resultMap);
            }
            orderId = String.valueOf(flyOrder.getId());
        } else {
            flyOrder = selectByOrderId(orderId);
            if(flyOrder==null){
                flyOrder = getOrderByFirstTransId(lastTransId);
                if (flyOrder == null) {
                    log.info("====@@@@======FlyaymentController TBCOKCallBack=======>>>lastTrans_id There is no query order");
                    resultMap.put("result", "FAILED!");
                    resultMap.put("message","orderId is null || getOrderByFirstTransId(lastTrans_id) get data is null");
                    return ResultEntity.fail("orderId is null || getOrderByFirstTransId(lastTrans_id) get data is null",500,resultMap);
                }
                orderId = String.valueOf(flyOrder.getId());
            }
        }
        if(StringUtils.isEmpty(lastTransId)){
            resultMap.put("result", "FAILED!");
            resultMap.put("source",flyOrder.getSource());
            resultMap.put("message","trans_ids Valye is null");
            return ResultEntity.fail("trans_ids Valye is null",500,resultMap);
        }
        String callBackResultStr = callBackByTransId(lastTransId);
        log.info("FlyaymentController TBCOKCallBack=======>>>======@@@@===pay info callBackResultStr===" + callBackResultStr + "@@@@==================");
        Map<String, String> callBackMap = getParsingCallBackMap(callBackResultStr);
        if(callBackMap==null){
            log.info("===========@@@@====FlyaymentController TBCOKCallBack=======>>>======@@@@===支付返回的信息是error信息");
            resultMap.put("source",flyOrder.getSource());
            resultMap.put("result", "FAILED!");
            resultMap.put("message","pay info return null");
            return ResultEntity.fail("pay info return null",500,resultMap);
        }
        String result = callBackMap.get("RESULT"), result_code = callBackMap.get("RESULT_CODE"), DSECURE = callBackMap.get("3DSECURE"), RRN = callBackMap.get("RRN"), APPROVAL_CODE = callBackMap.get("APPROVAL_CODE"), BANK_ID = callBackMap.get("CARD_NUMBER");
        log.info("====@@@@======FlyaymentController TBCOKCallBack=======>>> callBackResultStr slipt解析的结果是=====>result =" + result + ",   result_code=" + result_code + ",   DSECURE=" + DSECURE + ",    RRN=" + RRN + ",   APPROVAL_CODE=" + APPROVAL_CODE + ",    BANK_ID=" + BANK_ID + ",    orderId=" + orderId);

        String paymentResult = addTbcPaymentInfo(orderId, lastTransId, result, result_code, DSECURE, RRN, APPROVAL_CODE, BANK_ID, callBackResultStr, flyOrder.getFirstTransId(), "");
        if (paymentResult.equals("error")) {
            log.info("FlyaymentController TBCOKCallBack=======>>>======@@@@===添加支付信息失败");
        }
        resultMap.put("$order_number", flyOrder.getOrderId());
        resultMap.put("$order_amount", flyOrder.getTotalPrice() + "");
        resultMap.put("$order_currency", flyOrder.getCurrency());
        resultMap.put("source", flyOrder.getSource());
        if (result != null && result.equals("FAILED")) {
            TbcResultCode tbcResultCode = getTbcResultCode(result_code);
            if(tbcResultCode!=null){
                resultMap.put("message", "Pay FAILED Return Code is  " + tbcResultCode.getMsgFull());
            }else{
                resultMap.put("message", "Pay for failure");
            }
        } else if (result != null && result.equals("OK")) {
            //修改订单支付状态
            flyOrder.setOrderStatus(OrderStatus.HP.toString());
            orderService.updateByPrimaryKeySelective(flyOrder);
            //出票
            JsonData jsonData = ticketService.handleTicket(flyOrder.getOrderId());
            if (!jsonData.isRet()) {
                resultMap.put("result", "FAILED!");
                resultMap.put("message","The payment was successful but the invoice failed");
                return  ResultEntity.fail("The payment was successful but the invoice failed",500,resultMap);
            }
            resultMap.put("result", "SUCCESS");
            resultMap.put("message", "To Pay SUCCESS");
            JsonData data = orderService.findAllPnrByOrderID(orderId);
            if(data.isRet()){
                List<FlyPnr> flyPnrs = (List<FlyPnr>)data.getData();
                String pnrs = "";
                if(flyPnrs.size()>0) pnrs = "PNR：";
                for (FlyPnr flyPnr:flyPnrs) {
                    pnrs += flyPnr.getPnrNo()+",";
                }
                pnrs = pnrs.substring(0,pnrs.length()-1);
                resultMap.put("pnrs",pnrs);
            }
            return ResultEntity.success("The payment was made and the invoice was issued successfully",resultMap);
        } else {
            resultMap.put("message", "Returns an empty or parsing error");
        }
        flyOrder.setOrderStatus(OrderStatus.PV.toString());
        orderService.updateByPrimaryKeySelective(flyOrder);
        resultMap.put("result", "FAILED!");
        return ResultEntity.fail("Pay for FAILED",500,resultMap);
    }


    @Override
    public  boolean updateOrderPayInfo(String orderId,FlyOrder flyOrderInfo,String transId){
        if(flyOrderInfo.getOrderStatus().equals("XX")){
            return  false;
        }
        try {
            String firstTransId = flyOrderInfo.getFirstTransId();
            if(StringUtils.isEmpty(firstTransId)){
                flyOrderInfo.setLastTransId(transId);
            }else{
                String lastTransId = flyOrderInfo.getLastTransId();
                flyOrderInfo.setLastTransId(lastTransId + "(@@)" + transId);
            }
            flyOrderInfo.setFirstTransId(transId);
            flyOrderInfo.setUpdateDate(new Date());
            flyOrderInfo.setOrderStatus("PI");
            flyOrderInfo.setTransIdDate(new Date());
            int updateOrderNum = flyOrderMapper.updateByPrimaryKeySelective(flyOrderInfo);
            if(updateOrderNum<=0){
                return false;
            }
            return true;
        }catch (Exception e){
            System.out.println("====@@@=========》》》修改支付订单状态失败");
            e.printStackTrace();
            return false;
        }
    };

    //解析根据transId返回的支付结果
    @Override
    public Map<String, String> getParsingCallBackMap(String callBackResultStr){
        Map<String, String> callBackMap = new HashMap<String, String>();
        callBackResultStr = callBackResultStr.replaceAll("(\r\n|\r|\n|\n\r)", "<br>");
        //当返回 ERROR 直接返回
        String[] resultError = callBackResultStr.split(":");
        String s1 = resultError[0];
        if (callBackResultStr == null || s1.equals("ERROR")) {
            log.info("===========@@@@====FlyaymentController TBCOKCallBack=======>>>======@@@@===支付返回的信息是error信息");
            return null;
        }
        String[] data1 = callBackResultStr.split("<br>");
        if (data1 != null && data1.length > 0) {
            for (String s : data1) {
                String[] data2 = s.split(":");
                if (data2 != null && data2.length > 0)
                    callBackMap.put(data2[0].trim(), data2[1].trim());
            }
        }
        return  callBackMap;
    }

}
